﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Web.Mvc;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using Sherwood.SignOn.Server;
using Sherwood.SignOn.Server.Models;
using Sherwood.SignOn.Server.Models.ViewModels;
using Sherwood.SignOn.Server.Controllers;
using Sherwood.SignOn.Server.Models.Repositories;
using Sherwood.SignOn.Server.Models.Services;


namespace Sherwood.SignOn.Server.Tests
{
    [TestClass]
    public class ForgotPasswordTests : TestBase
    {
        /// <summary>
        /// Tests the reset password function.
        /// This should send a verification code (via email) and change the verification status to ResetPassword
        /// The password should remain unchanged (only changed in a later step).
        /// If username or email do not match an existing user, an error message should be displayed.
        /// </summary>
        [TestMethod]
        public void RequestResetPasswordTest()
        {
            //Assemble

            TestHelper.RegisterValidDummyUser("NewUser", "rvanoord@allmail.net");
            IUserAccount user = Data.UserAccounts.GetUserAccountByUsername("NewUser");
            UserAccountController accountController = new UserAccountController();
            ForgotPasswordViewModel accountViewModel = new ForgotPasswordViewModel();
            user.SetVerificationParameters(VerificationStatus.Verified, null, null);

            //Act
            ViewResult resultTestNoUsername = accountController.ForgotPassword(accountViewModel) as ViewResult;
            bool noUserNameErrors = TestHelper.HasError(accountController.ModelState);

            accountViewModel.UserName = "NonExistingUser";
            accountController = new UserAccountController();
            ViewResult resultTestWrongUsername = accountController.ForgotPassword(accountViewModel) as ViewResult;
            bool wrongUserNameErrors = TestHelper.HasError("UserName", accountController.ModelState);

            accountViewModel.UserName = "";
            accountViewModel.Email = "notarealemail@nowhere.com";
            accountController = new UserAccountController();
            ViewResult resultTestWrongEmail = accountController.ForgotPassword(accountViewModel) as ViewResult;
            bool wrongEmailErrors = TestHelper.HasError("Email",accountController.ModelState);
            VerificationStatus finalVerificationStatus0 = user.VerificationStatus;

            accountViewModel.UserName = "";
            accountViewModel.Email = "rvanoord@allmail.net";
            accountController = new UserAccountController();
            ViewResult resultCorrectEmail = accountController.ForgotPassword(accountViewModel) as ViewResult;
            user = Data.UserAccounts.GetUserAccountByUsername("NewUser"); //reload user
            bool correctEmailErrors = TestHelper.HasError(accountController.ModelState); ;
            VerificationStatus finalVerificationStatus1 = user.VerificationStatus;

            user.SetVerificationParameters(VerificationStatus.Verified, null, null);
            accountViewModel.UserName = "NewUser";
            accountViewModel.Email = null;
            accountController = new UserAccountController();
            ViewResult resultCorrectUsername = accountController.ForgotPassword(accountViewModel) as ViewResult;
            bool correctUserNameErrors = TestHelper.HasError(accountController.ModelState);
            user = Data.UserAccounts.GetUserAccountByUsername("NewUser"); //reload user
            VerificationStatus finalVerificationStatus2 = user.VerificationStatus;


            //Assert
            Assert.IsTrue(noUserNameErrors);
            Assert.IsTrue(wrongEmailErrors);
            Assert.IsTrue(wrongUserNameErrors);
            Assert.IsFalse(correctEmailErrors);
            Assert.IsFalse(correctUserNameErrors);
            Assert.IsTrue(finalVerificationStatus0 == VerificationStatus.Verified);
            Assert.IsTrue(finalVerificationStatus1 == VerificationStatus.ResetPassword);
            Assert.IsTrue(finalVerificationStatus2 == VerificationStatus.ResetPassword);
        }

    }
}
